﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ValidationFramework.Reflection
{
	/// <summary>
	/// Caches reflected members for high speed access
	/// </summary>
    public class ReflectionCache : IReflectionCache
	{
		// --- Fields

		private Dictionary<PropertyKey, CachedPropertyInfo> _propertyDictionary;
		private Dictionary<FieldKey, CachedFieldInfo> _fieldDictionary;
		private Dictionary<ParameterKey, CachedParameterInfo> _parameterDictionary;


		// --- Constructors

		/// <summary>
		/// Initializes a new instance of the InfoCache class.
		/// </summary>
		public ReflectionCache()
		{
			_propertyDictionary = new Dictionary<PropertyKey, CachedPropertyInfo>();
			_fieldDictionary = new Dictionary<FieldKey, CachedFieldInfo>();
			_parameterDictionary = new Dictionary<ParameterKey, CachedParameterInfo>();
		}


		// --- Methods

		public CachedPropertyInfo GetCachedProperty(PropertyKey key)
		{
			CachedPropertyInfo info;
			if (_propertyDictionary.TryGetValue(key, out info))
			{
				return info;
			}
			else
			{
				// create it and return it
				var property = key.ResolvePropertyInfo();
				_propertyDictionary.Add(key, new CachedPropertyInfo(property));
				return _propertyDictionary[key];
			}
		}
		public CachedFieldInfo GetCachedField(FieldKey key)
		{
			CachedFieldInfo info;
			if (_fieldDictionary.TryGetValue(key, out info))
			{
				return info;
			}
			else
			{
				// create it and return it
				var field = key.ResolveFieldInfo();
				_fieldDictionary.Add(key, new CachedFieldInfo(field));
				return _fieldDictionary[key];
			}
		}
		public CachedParameterInfo GetCachedParameter(ParameterKey key)
		{
			CachedParameterInfo info;
			if (_parameterDictionary.TryGetValue(key, out info))
			{
				return info;
			}
			else
			{
				// create it and return it
				var param = key.ResolveParameterInfo();
				_parameterDictionary.Add(key, new CachedParameterInfo(param));
				return _parameterDictionary[key];
			}
		}
	}
}
